import { getStore } from './util'
import store from '../store'
import router, { resetRouter } from '@/router'

/**
 * 格式化 权限架构数据
 * @param {*} permission_json
 */
export const formatAuthority = (permission_json) => {
  let modular = JSON.parse(permission_json).module
  return loopCheck(modular)
}

/**
 * 递归 添加check属性
 * @param {array} data
 * @returns
 */
const loopCheck = function (data) {
  data.map((item) => {
    if (Object.prototype.toString.call(item) == '[object Object]') {
      item.check = false

      for (let key in item) {
        if (Array.isArray(item[key])) {
          item[key] = loopCheck(item[key])
        }
      }
    }
    return item
  })

  return data
}

/**
 * 生成操作码
 */
export const generateOperationCode = (base_data, accountMode) => {
  let result = []

  for (let i = 0; i < base_data.length; i++) {
    let obj = {
      system_id: base_data[i].id,
      system_number_code: base_data[i].system_number_code,
      system_name: base_data[i].system_name,
      codes: loopGenerateCodes(base_data[i].modular, accountMode)
    }

    result.push(obj)
  }

  return result
}

/**
 * 权限对象 扁平化 拼接操作码
 * @param {*} data
 * @returns
 */
const loopGenerateCodes = (data, accountMode) => {
  let result = accountMode
    ? {
        identitys: [],
        others: []
      }
    : []

  data.forEach((item) => loop(item, []))

  return result

  /**
   * 递归方法 对象扁平化
   * @param {*} node
   * @param {*} path
   */
  function loop(node, path) {
    let is_arr = false
    let arr_key = ''

    /**
     *  判断当前层是否 含有数组，有表示没到最后一层
     *  is_arr 是否有数组
     *  arr_key 数组的key
     */
    for (let key in node) {
      if (Array.isArray(node[key])) {
        is_arr = true
        arr_key = key
      }
    }

    // 如果是数组
    if (is_arr) {
      path.push(node.operate_code)
      node[arr_key].forEach((item) => loop(item, path))
    } else {
      if (node.check) {
        let [modular_code, route_code] = path

        //是否账号模式
        if (accountMode) {
          //是否有 disabled 属性， 账号模式下，有该属性表示身份，无则表示额外
          if (node.hasOwnProperty('disabled')) {
            result.identitys.push(
              `${modular_code + route_code + node.operate_code}`
            )
          } else {
            result.others.push(
              `${modular_code + route_code + node.operate_code}`
            )
          }
        } else {
          result.push(`${modular_code + route_code + node.operate_code}`)
        }
      }
    }
  }
}

/**
 * 操作码 对应 系统权限数据结构
 * @param {*} codes
 * @param {Boolean} is_disabled
 * @param {Object} base_data
 * 01010001  01(模块) 01(路由) 0001(操作)
 */
export const codesToAuthorityCheck = (codes, is_disabled, base_data) => {
  let base_authority = base_data || getStore('new_roles')

  let result = []

  if (base_data) {
    result = base_data
  }

  for (let i = 0; i < codes.length; i++) {
    for (let j = 0; j < base_authority.length; j++) {
      if (codes[i].id === base_authority[j].id) {
        codesToObject(base_authority[j].modular, codes[i].codes, is_disabled)

        if (base_data) {
          result.map((item) => {
            if (item.id == base_authority[j].id) {
              item = base_authority[j]
            }
          })
        } else {
          result.push(base_authority[j])
        }

        break
      }
    }
  }

  return result
}

/**
 * 获取单系统 权限结构
 * @param {Array * 系统的modular初始数据} base_data
 * @param {Array * 系统的操作码集合} codes
 * @returns
 */
const codesToObject = (base_data, codes, is_disabled) => {
  let modular_code = getPathCode(codes, 0)
  let route_code = getPathCode(codes, 1)

  let result = []

  base_data.forEach((item) => loop(item, []))

  return result

  /**
   * 递归方法
   * @param {*} node
   * @param {*} path
   */
  function loop(node, path) {
    let is_arr = false
    let arr_key = ''

    /**
     *  判断当前层是否 含有数组，有表示没到最后一层
     *  is_arr 是否有数组
     *  arr_key 数组的key
     */
    for (let key in node) {
      if (Array.isArray(node[key])) {
        is_arr = true
        arr_key = key
      }
    }

    // 如果是数组
    if (is_arr) {
      path.push(node.operate_code)
      let path_str = path.join('')

      switch (path.length) {
        case 1:
          if (modular_code.includes(path_str)) {
            node.check = true
            result.push(node)

            node[arr_key].forEach((item) => loop(item, path))
          }
          break
        case 2:
          if (route_code.includes(path_str)) {
            node.check = true

            node[arr_key].forEach((item) => loop(item, path))
          }
          break
        default:
          break
      }

      // 如果需要禁用
      if (is_disabled) {
        node.disabled = true
      }
    } else {
      let [modular_code, route_code] = path

      let curr_code = `${modular_code + route_code + node.operate_code}`

      if (codes.includes(curr_code)) {
        node.check = true

        // 如果需要禁用
        if (is_disabled) {
          node.disabled = true
        }
      }
    }
  }
}

/**
 * 获取单系统 路径对应操作码 集合
 * @param {Array 系统操作码} codes
 * @param {Int 路径层级} index
 * @returns
 */
const getPathCode = (codes, index = 0) => {
  let result = new Set()

  for (let i = 0; i < codes.length; i++) {
    let code = ''
    switch (index) {
      case 0:
        code = codes[i].substring(0, 2)
        break
      case 1:
        code = codes[i].substring(0, 4)
        break
      case 2:
        code = codes[i]
        break
      default:
        break
    }

    result.add(code)
  }

  return Array.from(result)
}

/**
 * 10(公司) 01(系统) 01010001(操作码) 0001(项目)
 * @param {*} data
 */
export const formatPower = (data) => {
  let projects = new Set()
  let companys = []

  data.forEach((item, index) => {
    projects.add(item.substring(item.length - 4, item.length))

    companys.push({
      number_mark: item.substring(0, 2),
      codes: [],
      roles: new Set()
    })
  })

  companys = companyPower(data, noRepeat(companys))

  return {
    projects: Array.from(projects),
    companys
  }
}

/**公司 */
const companyPower = (data, companys) => {
  let result = companys.map((citem) => {
    data.forEach((item, index) => {
      if (item.substring(0, 2) == citem.number_mark) {
        citem.codes.push(item.substring(4, item.length - 4))
        citem.roles.add(citem.codes[citem.codes.length - 1].substring(0, 4))
      }
    })

    citem.codes = Array.from(new Set(citem.codes))
    citem.roles = Array.from(citem.roles)

    return citem
  })

  return result
}

/**
 * 公司去重
 */
function noRepeat(arr) {
  let temp = []
  for (let i = 0; i < arr.length; i++) {
    if (!temp.map((item) => item.number_mark).includes(arr[i].number_mark)) {
      temp.push(arr[i])
    }
  }

  return temp
}

/**路由鉴权 */
export function permissionAuthentiction(asyncRoutes, roles) {
  resetRouter()
  let accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
  store.commit('setRoutes', accessedRoutes)
  router.addRoutes(accessedRoutes)
}

function hasPermissionOption(subRoute, power) {
  if (subRoute.meta.code == power) {
    return true
  }

  return false
}

function hasPermission(asyncRoutes, role) {
  let res = {}

  for (let modular of asyncRoutes) {
    let routes = []

    for (let route of modular.children) {
      let routeRes = hasPermissionOption(route, role)
      routeRes && routes.push(route)
    }

    if (routes.length) {
      res = modular
      res.children = routes
      return res
    }
  }

  return false
}

function filterAsyncRoutes(asyncRoutes, roles) {
  let res = []

  for (let role of roles) {
    let route = hasPermission(asyncRoutes, role)

    route && res.push(route)
  }

  res.sort((a, b) => {
    return a.meta.sort - b.meta.sort
  })
  return res
}

/** 取项目一级项目和二级项目 */
export function returnProgram(baseList = [], currList = []) {
  let base_ids = baseList.map((item) => item.program_id)

  let map = new Map()
  for (let i = 0; i < baseList.length; i++) {
    map.set(
      baseList[i].program_id,
      baseList[i].child.map((item) => item.program_id)
    )
  }

  let program_pid = [] //一级项目集合
  let program_id = [] //二级项目集合

  let index = -1
  for (let i = 0; i < currList.length; i++) {
    index = base_ids.indexOf(currList[i])
    if (index > -1) {
      program_pid.push(currList[i])
      program_id = [...program_id, ...map.get(currList[i])]
    } else {
      program_id.push(currList[i])

      let keys = map.keys()
      for (let key of keys) {
        if (map.get(key).includes(currList[i]) && !program_pid.includes(key)) {
          program_pid.push(key)
          break
        }
      }
    }
  }

  return { program_pid, program_id }
}

/** 供应商区分
 * data 默认数据
 * key 拼接的字段
 */
export function returnToogleTypeList(data, key = 'program_name') {
  let map = new Map()
  for (let i = 0; i < data.length; i++) {
    if (map.has(data[i].name)) {
      data[map.get(data[i].name)].name =
        data[i].name + `(${data[map.get(data[i].name)][key]})`
      data[i].name = data[i].name + `(${data[i][key]})`
    } else {
      map.set(data[i].name, i)
    }
  }
  return data
}
